import config from "@/common/config.js"
import "ol/ol.css";
import axios from 'axios'
import 'ol/ol.css';
import Map from 'ol/Map';
import VectorSource from 'ol/source/Vector';
import View from 'ol/View';
import XYZ from 'ol/source/XYZ';
import Overlay from 'ol/Overlay';
import {
	GeoJSON,
	WFS
} from 'ol/format';
import {
	Circle as CircleStyle,
	Fill,
	Stroke,
	Style,
	Icon
} from 'ol/style';
import {
	Control,
	defaults as defaultControls
} from 'ol/control';
import {
	intersects as intersectsFilter,
} from 'ol/format/filter';
import {
	bbox as bboxStrategy
} from 'ol/loadingstrategy';
import Feature from 'ol/Feature';
import {
	GeometryCollection,
	Point,
	Polygon,
	LineString,
	Circle
} from 'ol/geom';
import {
	toSize
} from 'ol/size';
import TileWMS from "ol/source/TileWMS"
import duobianx from "@/common/duobianx.json"
import point from "@/common/point.json"
import line from "@/common/line.json"
import {
	Draw,
	Modify,
	Snap,
	Select,
	defaults as defaultInteractions,
} from 'ol/interaction';
import {
	OSM,
	Vector as sourceVector
} from 'ol/source';
import {
	Tile as TileLayer,
	Vector as VectorLayer
} from 'ol/layer';
import {
	circular
} from 'ol/geom/Polygon';
import {
	getDistance
} from 'ol/sphere';
import {
	transform,
	applyTransform
} from 'ol/proj';
let deafalutIcon =
	"";

export class mapObject {
	/**
	 * 构造函数初始化map 对象
	 * @param {Object} id map容器ID
	 * @param {Object} center 中心点
	 * @param {Object} callback 点击事件回调
	 */
	constructor(id, center, callback, isWms) {
		this.center = center;
		if (isWms) {
			let wmsVsource = new TileWMS({
				//此处替换为自有wms
				url: "http://xx.xx.xx.xx:9000/geoserver/BeiJing/wms?LAYERS=BeiJing:BJVector1",
				parmas: {
					'LAYERS': ['BeiJing:BJVector1'],
					'TILED': true,
					"CRS": "EPSG:4326",
					"SRS": "EPSG:4326",
					"STYLES": "",
					"tileSize": [256, 256],
					"exceptions": 'application/vnd.ogc.se_inimage'
				},
				serverType: 'geoserver',
			});
			this.wmslayer = new TileLayer({
				source: wmsVsource
			});
		} else {
			this.weiLayer = new TileLayer({
				source: new XYZ({
					url: config.tianImg
				}),
				visible: true,
				zIndex: 0
			});
			this.xinLayer = new TileLayer({
				source: new XYZ({
					url: config.tianVec
				}),
				visible: false,
				zIndex: 0
			});
			this.lableLayer = new TileLayer({
				source: new XYZ({
					url: config.tianLabel
				}),
				visible: true,
				zIndex: 0
			});
		}

		const style = new Style({
			fill: new Fill({
				color: 'rgba(255, 255, 255, 0.2)',
			}),
			stroke: new Stroke({
				color: '#33cc33',
				width: 3,
			}),
			image: new CircleStyle({
				radius: 7,
				fill: new Fill({
					color: '#ffcc33',
				}),
			}),
		});
		const geodesicStyle = new Style({
			geometry: function(feature) {
				return feature.get('modifyGeometry') || feature.getGeometry();
			},
			fill: new Fill({
				color: 'rgba(255, 255, 255, 0.2)',
			}),
			stroke: new Stroke({
				color: '#ff3333',
				width: 3,
			}),
			image: new CircleStyle({
				radius: 7,
				fill: new Fill({
					color: 'rgba(0, 0, 0, 0)',
				}),
			}),
		});
		//线，面与手动绘制共用图层使用的资源
		this.sourceVector = new sourceVector({
			wrapX: false
		});
		this.vectorLayer = new VectorLayer({
			source: this.sourceVector,
			style: function(feature) {
				const geometry = feature.getGeometry();
				return geometry.getType() === 'GeometryCollection' ? geodesicStyle : style;
			}
		});
		//点使用的资源
		this.pointLayer = new VectorLayer();
		this.pointSourceVector = new sourceVector();
		this.pointLayer.setSource(this.pointSourceVector);
		//初始化map对象
		this.map = new Map({
			view: new View({
				center: this.center,
				projection: 'EPSG:4326',
				zoom: 11,
				minZoom: 4,
				maxZoom: 18
			}),
			target: id
		});
		if (isWms) {
			this.map.addLayer(this.wmslayer);
		} else {
			this.map.addLayer(this.weiLayer);
			this.map.addLayer(this.xinLayer);
			this.map.addLayer(this.lableLayer);
		}
		this.map.addLayer(this.vectorLayer);
		this.map.addLayer(this.pointLayer);
		//map添加点击事件
		this.map.on('singleclick', (e) => {
			let pixel = this.map.getEventPixel(e.originalEvent);
			// let Features = this.map.getFeaturesAtPixel(pixel);
			// console.log("获取到的Features",Features);
			let feature = this.map.forEachFeatureAtPixel(pixel,
				function(feature, layer) {
					return feature;
				});
			if (feature) {
				if (feature.getGeometry().getType() == 'Point') {
					this.select.setActive(false);
				} else {
					this.select.setActive(true);
				}
				let property = feature.getProperties();
				let type = feature.getGeometry().getType();
				callback(feature);
			}
		});

	}

	//================================手动绘制功能开始=======================================

	/**
	 * 初始化绘制编辑
	 * @param {Object} callback 编辑事件回调
	 */
	initModify(callback) {
		this.select = new Select({
			wrapX: false,
		});
		const defaultStyle = new Modify({
				source: this.sourceVector
			})
			.getOverlay()
			.getStyleFunction();
		this.modify = new Modify({
			features: this.select.getFeatures(),
			source: this.sourceVector,
		});
		this.modify.on('modifystart', function(event) {
			event.features.forEach(function(feature) {
				const geometry = feature.getGeometry();
				if (geometry.getType() === 'GeometryCollection') {
					feature.set('modifyGeometry', geometry.clone(), true);
				}
			});
		});
		this.modify.on('modifyend', function(event) {
			callback(event);
			event.features.forEach(function(feature) {
				const modifyGeometry = feature.get('modifyGeometry');
				if (modifyGeometry) {
					feature.setGeometry(modifyGeometry);
					feature.unset('modifyGeometry', true);
				}
				console.log(feature.getGeometry().getCoordinates());
			});
		});
		this.map.addInteraction(this.modify);
		this.map.addInteraction(this.select);
		this.select.on('select', e => {
			this.selectFeature = e.target.getFeatures();
		})
	}

	/**
	 * 绘制 点 线 面
	 * @param {Object} type  point line Polygon Circle
	 * @param {Object} endCallback 绘制完成回调
	 */
	addDrawInteractions(type, endCallback) {
		this.draw = new Draw({
			source: this.vectorLayer.getSource(),
			type: type ? type : "Polygon",
		});
		this.draw.on("drawend", e => {
			console.log("绘制完成", e.feature.getGeometry().getCoordinates());
			this.draw.setActive(false); //关闭绘制交互
			this.select.setActive(false);
			this.select.setActive(false);
			this.draw.finishDrawing(); //绘制完成
			endCallback(e);
		})
		this.map.addInteraction(this.draw);
	}

	/**
	 * 撤销点
	 */
	removeLastPoint() {
		this.draw.removeLastPoint();
		this.modify.removePoint();
	}

	/**
	 * 删除要素
	 */
	drawDelete() {
		try {
			this.selectFeature.forEach(item => {
				this.vectorLayer.getSource().removeFeature(item);
			})
		} catch (e) {
			console.log(e);
		}
	}

	/**
	 * 绘制完成
	 */
	drawComplete() {
		if (this.draw) {
			this.draw.setActive(false);
			this.draw.finishDrawing();
		}
		if (this.select) {
			this.select.setActive(false);
			this.select.getFeatures().clear();
		}
	}
	//================================手动绘制功能结束=======================================


	/**
	 * geoJson加载点线面
	 */
	drawPolygonGeoJson(geoJson) {
		let style = new Style({
			stroke: new Stroke({
				color: '#ff5722',
				width: 1,
			}),
			fill: new Fill({
				color: 'rgba(171,54,65, 0.3)'
			}),
		});
		this.vectorLayer.setStyle(style);
		this.sourceVector.addFeatures((new GeoJSON()).readFeatures(geoJson));
	}


	/**
	 * 绘制点
	 * @param {Object} genjson
	 */
	drawPointGeoJson(geoJson, icon) {
		let iconStyle = new Style({
			image: new Icon(({
				anchor: [0.5, 46],
				anchorXUnits: 'fraction',
				anchorYUnits: 'pixels',
				size: toSize({
					size: [20, 20]
				}),
				src: icon ? icon : deafalutIcon
			}))
		});
		this.pointLayer.setStyle(iconStyle);
		this.pointSourceVector.addFeatures((new GeoJSON()).readFeatures(geoJson));
	}

	/**
	 * 设置中心点
	 * @param {Object} center
	 */
	setMapCenter(center) {
		this.map.getView().setCenter(center);
	}

	/**
	 * 定位中心点绘制
	 */
	drawMark(ponit, icon) {
		if (this.centerLayer != null || this.centerLayer != undefined) {
			this.map.removeLayer(this.centerLayer)
		}
		let iconFeature = new Feature({
			geometry: new Point(ponit),
			name: 'marks',
			population: 4000,
			rainfall: 500
		});

		let iconStyle = new Style({
			image: new Icon(({
				anchor: [0.5, 46],
				anchorXUnits: 'fraction',
				anchorYUnits: 'pixels',
				scale:0.3,
				src: icon ? icon : deafalutIcon
			}))
		});
		iconFeature.setStyle(iconStyle);
		let vectorSource = new sourceVector({
			features: [iconFeature]
		});
		this.centerLayer = new VectorLayer({
			source: vectorSource
		});
		this.map.addLayer(this.centerLayer);
	}


	/**
	 * 绘制点
	 */
	drawPoint(ponit, icon) {
		let iconFeature = new Feature({
			geometry: new Point(ponit),
			name: 'marks',
			population: 4000,
			rainfall: 500
		});
		let iconStyle = new Style({
			image: new Icon(({
				anchor: [0.5, 46],
				anchorXUnits: 'fraction',
				anchorYUnits: 'pixels',
				scale:0.3,
				src: icon ? icon : deafalutIcon
			}))
		});
		iconFeature.setStyle(iconStyle);
		this.pointSourceVector.addFeature(iconFeature);
	}

	/**
	 * 绘制多边形
	 */
	drawPolygon(polyCoords) {
		let polygon = new Polygon(polyCoords);
		let iconFeature = new Feature(polygon);
		let style = new Style({
			stroke: new Stroke({
				color: '#ff5722',
				width: 3,
			}),
			fill: new Fill({
				color: 'rgba(171,54,65, 0.3)'
			}),
		});
		iconFeature.setStyle(style);
		this.sourceVector.addFeature(iconFeature);
	}

	/**
	 * 绘制线
	 */
	drawLine(coordinates) {
		let lineString = new LineString(coordinates);
		let style = new Style({
			stroke: new Stroke({
				color: '#ff00ff',
				width: 3,
			}),
			fill: new Fill({
				color: 'rgba(171,54,65, 0.3)'
			}),
		});
		let lineFeature = new Feature(lineString);
		lineFeature.setStyle(style);
		this.sourceVector.addFeature(lineFeature);
	}
	
	/**
	 * 隐藏原有的按钮
	 */
	hideOption() {
		let olControl = document.getElementsByClassName("ol-zoom-in");
		let olControlOut = document.getElementsByClassName("ol-zoom-out");
		olControl[0].style.display = "none"
		olControlOut[0].style.display = "none"
	}

	/**
	 * 行政图与影像图层切换
	 */
	changeLayer(isShow) {
		if (isShow) {
			this.weiLayer.setVisible(true);
			this.xinLayer.setVisible(false);
		} else {
			this.weiLayer.setVisible(false);
			this.xinLayer.setVisible(true);
		}
	}

	/**
	 * 缩小
	 */
	zoomSmall() {
		let view = this.map.getView();
		let zoom = view.getZoom();
		view.setZoom(zoom - 1);
	}

	/**
	 * 放大
	 */
	zoomBig() {
		let view = this.map.getView();
		let zoom = view.getZoom();
		view.setZoom(zoom + 1);
		this.getViewPort();
	}

	/**
	 * 获取可视区域
	 */
	setViewPortChange(callback) {
		this.map.on("moveend", e => {
			let view = this.map.getView();
			let array = view.calculateExtent(this.map.getSize());
			callback(array);
		})
	}
}
